package com.retail.lottery.colalottery.job.node;

import com.alibaba.fastjson.JSON;
import com.retail.lottery.colalottery.constant.RedisConstant;
import com.retail.lottery.colalottery.utils.NetWorkUtil;
import com.retail.lottery.colalottery.vo.NodeInfoVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.retail.lottery.colalottery.constant.RedisConstant.REDIS_KEY_NODE_HASH_KEY;

@Service
@Slf4j
public abstract class RedisNodeIpManager {
    @Resource
    private RedisTemplate<String, String> redisTemplate;

    /**
     * 节点注册
     */
    public void registerNode(String nodeIp) {
        HashOperations<String, String, String> hashOps = redisTemplate.opsForHash();
        // 以当前时间戳作为节点活跃标记
        hashOps.put(RedisConstant.REDIS_KEY_NODE_HASH_KEY, nodeIp, String.valueOf(System.currentTimeMillis()));
        // 自动清理过期时间
        redisTemplate.expire(RedisConstant.REDIS_KEY_NODE_HASH_KEY, 2, TimeUnit.MINUTES);
    }

    /**
     * 获取所有活跃节点IP列表
     */
    public List<String> getAllNodes() {
        HashOperations<String, String, String> hashOps = redisTemplate.opsForHash();
        Map<String, String> nodeMap = hashOps.entries(RedisConstant.REDIS_KEY_NODE_HASH_KEY);

        // 过滤超过3分钟的不活跃节点
        long currentTime = System.currentTimeMillis();
        return nodeMap.entrySet().stream()
                .filter(entry -> currentTime - Long.parseLong(entry.getValue()) < 3 * 60 * 1000)
                .map(Map.Entry::getKey)
                .sorted()
                .collect(Collectors.toList());
    }

    /**
     * 获取当前节点的ID
     */
    public int getNodeId(String nodeIp) {
        List<String> nodes = getAllNodes();
        return nodes.indexOf(nodeIp);
    }


    public NodeInfoVo localNodeInfo() {
        //1.获取本机内网IP
        String localIp = NetWorkUtil.getLocalIp();
        //2.注册到Redis
        registerNode(localIp);
        // 3. 获取节点ID
        List<String> allNodes = getAllNodes();
        int nodeId = getNodeId(localIp);
        log.info("集群所有节点: {}", JSON.toJSONString(getAllNodes()));
        log.info("当前节点IP:{},节点ID：{}", localIp, nodeId);
        return new NodeInfoVo(allNodes.size(), nodeId);
    }
}
